package com.example.tedtalksimproved;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ClearCacheRequest;
import com.android.volley.toolbox.StringRequest;
import com.example.tedtalksimproved.adapter.VideoListAdapter;
import com.example.tedtalksimproved.cache.MyVolley;
import com.example.tedtalksimproved.loader.VideoInfo;
import com.example.tedtalksimproved.loader.XMLParser;

/**
 * A list fragment representing a list of Videos. This fragment also supports
 * tablet devices by allowing list items to be given an 'activated' state upon
 * selection. This helps indicate which item is currently being viewed in a
 * {@link VideoDetailFragment}.
 * <p>
 * Activities containing this fragment MUST implement the {@link Callbacks}
 * interface.
 */
public class VideoListFragment extends ListFragment {

	// ArrayList for storing VideoInfo objects
	public static ArrayList<VideoInfo> mEntries = new ArrayList<VideoInfo>();
	public static ArrayList<VideoInfo> mAll = new ArrayList<VideoInfo>();
	public static ArrayList<VideoInfo> mFavorites = new ArrayList<VideoInfo>();
	// We use a custom ArrayAdapter to bind application info to the ListView.
	public static VideoListAdapter mAdapter;
	// XML node keys
	static final String KEY_ITEM = "channel"; // parent node
	static final String KEY_TITLE = "itunes:subtitle";
	static final String KEY_DESCRIPTION = "description";
	static final String KEY_THUMBNAIL = "media:thumbnail";
	static final String KEY_VIDEO = "media:content";
	static final String KEY_DATE = "pubDate";
	static final String KEY_DURATION = "itunes:duration";
	static final String KEY_CATOGORY = "category";
	// Booleans for checking if there is any data available
	private boolean mHasData = false;
	private boolean mInError = false;
	// Log boolean
	public static boolean logOn = true;
	// View either all = true or favorites = false
	public static boolean viewInFront = true;

	/**
	 * The serialization (saved instance state) Bundle key representing the
	 * activated item position. Only used on tablets.
	 */
	private static final String STATE_ACTIVATED_POSITION = "activated_position";

	/**
	 * The current activated item position. Only used on tablets.
	 */
	private int mActivatedPosition = ListView.INVALID_POSITION;

	/**
	 * The fragment's current callback object, which is notified of list item
	 * clicks.
	 */
	private Callbacks mCallbacks = sDummyCallbacks;

	/**
	 * A callback interface that all activities containing this fragment must
	 * implement. This mechanism allows activities to be notified of item
	 * selections.
	 */
	public interface Callbacks {
		/**
		 * Callback for when an item has been selected.
		 */
		public void onItemSelected(String id);
	}

	/**
	 * A dummy implementation of the {@link Callbacks} interface that does
	 * nothing. Used only when this fragment is not attached to an activity.
	 */
	private static Callbacks sDummyCallbacks = new Callbacks() {
		@Override
		public void onItemSelected(String id) {
		}
	};

	/**
	 * Mandatory empty constructor for the fragment manager to instantiate the
	 * fragment (e.g. upon screen orientation changes).
	 */
	public VideoListFragment() {
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}

	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {
		super.onViewCreated(view, savedInstanceState);
		// Restore the previously serialized activated item position.
		if (savedInstanceState != null
				&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
			setActivatedPosition(savedInstanceState
					.getInt(STATE_ACTIVATED_POSITION));
		}
		MyVolley.init(getActivity());
		mAdapter = new VideoListAdapter(getActivity(), 0, mEntries,
				MyVolley.getImageLoader());
		setListAdapter(mAdapter);
		setListShown(false);
		if (mEntries.size() == 0)
			loadPage();
		else {
			if (viewInFront)
				screenflipHome();
			else
				screenflipFavorites();
		}
	}

	public void onResume() {
		super.onResume();
		if (!mHasData && !mInError) {

		}
	}

	private void loadPage() {
		RequestQueue queue = MyVolley.getRequestQueue();

		StringRequest request = new StringRequest(Request.Method.GET,
				"http://feeds.feedburner.com/tedtalks_video",
				createMyReqSuccessListener(), createMyReqErrorListener());
		queue.add(request);
	}

	private Response.Listener<String> createMyReqSuccessListener() {
		return new Response.Listener<String>() {
			@Override
			public void onResponse(String response) {

				XMLParser parser = new XMLParser();
				Document doc = parser.getDomElement(response); // getting DOM
																// element
				if (logOn = true)
					Log.d("onResponce", "Setting all data to nodelists");
				// getting all usable data nodelists
				NodeList titles = doc.getElementsByTagName(KEY_TITLE);
				NodeList thumbnails = doc.getElementsByTagName(KEY_THUMBNAIL);
				NodeList descriptions = doc
						.getElementsByTagName(KEY_DESCRIPTION);
				NodeList durations = doc.getElementsByTagName(KEY_DURATION);
				NodeList dates = doc.getElementsByTagName(KEY_DATE);
				NodeList categories = doc.getElementsByTagName(KEY_CATOGORY);
				NodeList videos = doc.getElementsByTagName(KEY_VIDEO);

				// looping through all item nodes
				for (int i = 2; i < titles.getLength(); i++) {
					if (logOn = true)
						Log.d("onResponce", "Getting all elements");
					Element title = (Element) titles.item(i);
					Element thumbnail = (Element) thumbnails.item(i - 1);
					Element description = (Element) descriptions.item(i - 1);
					Element duration = (Element) durations.item(i - 2);
					Element date = (Element) dates.item(i - 2);
					Element category = (Element) categories.item(i - 1);
					Element video = (Element) videos.item(i - 1);

					VideoInfo entry = new VideoInfo(
							thumbnail.getAttribute("url"),
							parser.getElementValue(duration),
							parser.getElementValue(date),
							parser.getElementValue(category),
							parser.getElementValue(description),
							video.getAttribute("url"));// Image,
														// Duration,
														// Date,
														// Category,
														// Description
														// Video
					entry.setTitleAndAuthor(parser.getElementValue(title));
					mAll.add(entry);

				}
				if (logOn = true)
					Log.d("onResponce",
							"All VideoInfo objects added to ArrayList<VideoInfo>");
				setListShown(true);
				openHome();

			}

		};
	}

	private Response.ErrorListener createMyReqErrorListener() {
		return new Response.ErrorListener() {
			@Override
			public void onErrorResponse(VolleyError error) {
				showErrorDialog();
			}
		};
	}

	private void showErrorDialog() {
		mInError = true;
		if (logOn = true)
			Log.d("showErrorDialog",
					"Error occured somewhere within Volley loading and proccessing result");
	}

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		// Activities containing this fragment must implement its callbacks.
		if (!(activity instanceof Callbacks)) {
			throw new IllegalStateException(
					"Activity must implement fragment's callbacks.");
		}

		mCallbacks = (Callbacks) activity;
	}

	@Override
	public void onDetach() {
		super.onDetach();
		// Reset the active callbacks interface to the dummy implementation.
		mCallbacks = sDummyCallbacks;
	}

	@Override
	public void onListItemClick(ListView listView, View view, int position,
			long id) {
		super.onListItemClick(listView, view, position, id);
		Log.d("onListItemClick", "List item was clicked");
		mCallbacks.onItemSelected(position + "");

	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		if (mActivatedPosition != ListView.INVALID_POSITION) {
			// Serialize and persist the activated item position.
			outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
		}
	}

	/**
	 * Turns on activate-on-click mode. When this mode is on, list items will be
	 * given the 'activated' state when touched.
	 */
	public void setActivateOnItemClick(boolean activateOnItemClick) {
		// When setting CHOICE_MODE_SINGLE, ListView will automatically
		// give items the 'activated' state when touched.
		getListView().setChoiceMode(
				activateOnItemClick ? ListView.CHOICE_MODE_SINGLE
						: ListView.CHOICE_MODE_NONE);
	}

	private void setActivatedPosition(int position) {
		if (position == ListView.INVALID_POSITION) {
			getListView().setItemChecked(mActivatedPosition, false);
		} else {
			getListView().setItemChecked(position, true);
		}

		mActivatedPosition = position;
	}

	public void openFavorites() {
		if (logOn = true)
			Log.d("openFavorites", "setting favorites");
		mEntries.clear();
		mEntries.addAll(mFavorites);
		mAdapter.notifyDataSetChanged();
		viewInFront = false;
	}

	public void screenflipHome() {
		mEntries.clear();
		mEntries.addAll(mAll);
		mAdapter.notifyDataSetChanged();
		viewInFront = true;
		setListShown(true);
	}

	public void openHome() {
		mEntries.clear();
		mEntries.addAll(mAll);
		mAdapter.notifyDataSetChanged();
		viewInFront = true;
	}
	
	

	public void addToFavorites(VideoInfo item) {
		mFavorites.add(item);
		item.setFavorite(true);
	}

	public void screenflipFavorites() {
		mEntries.clear();
		mEntries.addAll(mFavorites);
		mAdapter.notifyDataSetChanged();
		viewInFront = false;
		setListShown(true);
	}

	public void removeFromFavorites(VideoInfo item) {
		item.setFavorite(false);
		mFavorites.remove(item);
		mEntries.clear();
		mEntries.addAll(mFavorites);
		mAdapter.notifyDataSetChanged();
	}
}
